package com.systop.common.modules.security.acegi.filter;

import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.acegisecurity.Authentication;
import org.acegisecurity.context.SecurityContext;
import org.acegisecurity.context.SecurityContextHolder;
import org.acegisecurity.ui.webapp.AuthenticationProcessingFilter;
import org.acegisecurity.userdetails.UserDetails;
import org.springframework.beans.factory.annotation.Autowired;

import com.systop.common.modules.security.acegi.listener.UserLoginListener;
import com.systop.common.modules.security.user.model.User;
import com.systop.common.modules.security.user.service.UserManager;
import com.systop.core.Constants;

/**
 * 把User变量放入http session中,key为Constants.USER_IN_SESSION
 * 
 * @author cac,sam,nice
 */
public class UserAuthenticationProcessingFilter extends
		AuthenticationProcessingFilter {

	@Autowired
	private List<UserLoginListener> userLoginListeners;

	public void setUserLoginListeners(List<UserLoginListener> userLoginListeners) {
		this.userLoginListeners = userLoginListeners;
	}

	@Autowired
	private UserManager userManager;

	/**
	 * @see {@link org.acegisecurity.ui. AbstractProcessingFilter#requiresAuthentication}
	 */
	protected boolean requiresAuthentication(HttpServletRequest request,
			HttpServletResponse response) {
		boolean requiresAuth = super.requiresAuthentication(request, response);
		HttpSession session = null;
		try {
			session = request.getSession(false);
		} catch (IllegalStateException ignored) {
		}
		if (session != null) {
			if (session.getAttribute(Constants.USER_IN_SESSION) == null) {
				if (!requiresAuth) {
					SecurityContext sc = SecurityContextHolder.getContext();
					Authentication auth = sc.getAuthentication();
					if (auth != null
							&& auth.getPrincipal() instanceof UserDetails) {
						UserDetails ud = (UserDetails) auth.getPrincipal();
						User user = userManager.getUser(ud.getUsername(),
								ud.getPassword());
						session.setAttribute(Constants.USER_IN_SESSION, user);
						// 更新用户登录信息，例如登录次数等
						fireLoginSuccessedEvents(user, request);
					} else {
						fireLoginFailedEvents(request);
					}
				}
			}
		}
		return requiresAuth;
	}

	/** 执行用户登录成功事件  */
	private void fireLoginSuccessedEvents(User user, HttpServletRequest request) {
		if (userLoginListeners != null) {
			for (UserLoginListener listener : userLoginListeners) {
				listener.loginSuccessed(user, request);
			}
		}
	}

	/** 执行用户登录成功事件 */
	private void fireLoginFailedEvents(HttpServletRequest request) {
		if (userLoginListeners != null) {
			for (UserLoginListener listener : userLoginListeners) {
				listener.loginFailed(request);
			}
		}
	}

}
